home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************************************
-
- mac_scroll.c: Copyright (c) Kevin Hammond 1993. All rights reserved.
-
- Routines to handle window scroll bars -- only the front window
- may be scrolled in this way.
-
- *****************************************************************************/
-
-
- #include "mac.h"
-
- #pragma segment Scroll
-
- #define HORIZ_SCALE 10 /* scale factor to speed horizontal scrolling */
-
- #define InactiveScroll 255
- #define ActiveScroll 0
-
-
- pascal void ScrollText(ControlHandle scrollbar, short thePart);
-
- static Boolean vscroll = TRUE; /* Whether scrolling vertically or horizontally */
-
-
-
- /*
- Scroll a window according to whether the thumb bar's been hit,
- the current point and whether we're scrolling vertically or
- horizontally.
- */
-
- DoScroll(thePart,thePoint,vertical)
- short thePart;
- Point thePoint;
- short vertical;
- {
- if(isLegalWindow(thefrontwindow))
- {
- ControlHandle scrollbar = vertical? VSCROLL(thefrontwindow):
- HSCROLL(thefrontwindow);
-
- if(thePart == inThumb)
- {
- thePart = TrackControl(scrollbar,thePoint,(ProcPtr)NIL);
- AdjustText(thefrontwindow);
- }
- else if (thePart != 0)
- {
- vscroll = vertical;
- thePart = TrackControl(scrollbar,thePoint,(ProcPtr)ScrollText);
- }
- }
- }
-
-
-
- /*
- Scroll vertically.
- */
-
- void ScrollVText(scrollbar,vertical,thePart)
- ControlHandle scrollbar;
- short thePart;
- Boolean vertical;
- {
- vscroll = vertical;
- ScrollText(scrollbar,thePart);
- }
-
-
- /*
- Handle a scrolling motion for the scroll bar, and adjust
- the text to suit. Called from within an autotracking
- routine, so vscroll needs to be set outside this to
- indicate whether we're scrolling vertically or horizontally.
- */
-
- pascal void ScrollText(scrollbar,thePart)
- ControlHandle scrollbar;
- short thePart;
- {
-
- if(isLegalWindow(thefrontwindow))
- {
- short delta = 0;
- Rect vr;
-
- TEHLock(thefrontwindow);
-
- vr = (*TEHANDLE(thefrontwindow))->viewRect;
-
- switch(thePart)
- {
- case inUpButton:
- delta = -1;
- break;
-
- case inDownButton:
- delta = 1;
- break;
-
- case inPageUp:
- if(vscroll)
- delta = (vr.top-vr.bottom)/(*TEHANDLE(thefrontwindow))->lineHeight -1;
- else
- delta = (vr.left-vr.right)/HORIZ_SCALE - 1;
- break;
-
- case inPageDown:
- if(vscroll)
- delta = (vr.bottom-vr.top)/(*TEHANDLE(thefrontwindow))->lineHeight -1;
- else
- delta = (vr.right-vr.left)/HORIZ_SCALE - 1;
- break;
- }
-
- TEHUnlock(thefrontwindow);
-
- if(thePart!=0 && delta != 0)
- {
- short old = GetCtlValue(scrollbar);
- short new = old+delta;
- short max;
-
- if(new <= 1)
- SetCtlValue(scrollbar,1);
-
- else if(new >= (max = GetCtlMax(scrollbar)))
- {
- if( old < max )
- SetCtlValue(scrollbar,max);
- }
-
- else
- SetCtlValue(scrollbar,old+delta);
-
- AdjustText(thefrontwindow);
- }
- }
- }
-
-
-
- /*
- Scroll the text in the window to match the positions of the
- scroll bars.
- */
-
- AdjustText(windex)
- int windex;
- {
- if(isLegalWindow(windex))
- {
- short old, new;
-
- TEHandle teh = TEHANDLE(windex);
-
- /* vertical scroll bars */
- old = (*teh)->viewRect.top - (*teh)->destRect.top;
- new = (GetCtlValue(VSCROLL(windex))-1)*(*teh)->lineHeight;
- TEScroll(0,old-new,teh);
-
- /* horizontal scroll bars */
- old = (*teh)->viewRect.left - (*teh)->destRect.left;
- new = (GetCtlValue(HSCROLL(windex))-1)*HORIZ_SCALE;
- TEScroll(old-new,0,teh);
- }
- }
-
-
-
- /*
- Set the scroll bars correctly.
- This version prevents Gofer from scrolling up when the first character
- is typed and the cursor's at the bottom of the window.
- */
-
-
- AdjustScrollBars(windex)
- int windex;
- {
- if(isLegalWindow(windex))
- {
- TEPtr teptr = *TEHANDLE(windex);
-
- Rect vr = teptr->viewRect;
- Rect dr = teptr->destRect;
-
- short lineHeight = teptr->lineHeight;
- short windowHeight = (vr.bottom-vr.top)/lineHeight;
- short windowWidth = (vr.right-vr.left);
-
- /* We need an extra line if the last character is a newline */
- Boolean extraLineNeeded = *( *teptr->hText + (teptr->teLength - 1) ) == '\n';
- short maxHeight = teptr->nLines + (extraLineNeeded ? 2 : 1) - windowHeight;
- short maxWidth = (dr.right - dr.left - windowWidth)/HORIZ_SCALE+2;
-
- setcontrolmax(VSCROLL(windex),maxHeight);
- setcontrolmax(HSCROLL(windex),maxWidth);
- }
- }
-
-
- /*
- Set a new maximum value for a control.
- If this is one, deactivate the control.
- */
-
- setcontrolmax(control,value)
- ControlHandle control;
- short value;
- {
- if(value <= 1)
- {
- value = 1;
- HiliteControl(control,InactiveScroll);
- }
- else
- HiliteControl(control,ActiveScroll);
-
- SetCtlMax(control,value);
- }
-
-
- /*
- The routine which is called automatically when the
- mouse is down in the scrollbar.
- */
-
- pascal Boolean AutoScroll()
- {
- if(isLegalWindow(thefrontwindow))
- {
- Point mousePt;
- Rect tempRect;
-
- RgnHandle saveClip = NewRgn();
-
- GetClip(saveClip);
- ClipRect(&(WINDOW(thefrontwindow)->portRect));
- GetMouse(&mousePt);
- tempRect = (*TEHANDLE(thefrontwindow))->viewRect;
-
- if(mousePt.v < tempRect.top)
- ScrollVText(VSCROLL(thefrontwindow),TRUE,inUpButton);
-
- else if(mousePt.v > tempRect.bottom)
- ScrollVText(VSCROLL(thefrontwindow),TRUE,inDownButton);
-
- else if(mousePt.h < tempRect.left)
- ScrollVText(HSCROLL(thefrontwindow),FALSE,inUpButton);
-
- else if(mousePt.h > tempRect.right)
- ScrollVText(HSCROLL(thefrontwindow),FALSE,inDownButton);
-
- SetClip(saveClip);
- DisposeRgn(saveClip);
- }
- return(TRUE);
- }
-
-
- /*
- Scroll a window to the character whose position is given.
- If tobottom is set, then we are scrolling downwards, so
- it is acceptable to scroll one position past the maximum.
- */
-
- ScrollCharacter(windex,posn,tobottom)
- int windex;
- short posn;
- Boolean tobottom;
- {
- if(isLegalWindow(windex))
- {
- TEHandle teh = TEHANDLE(windex);
- short i;
-
- /* find line start corresponding to posn */
- for(i=1;(*teh)->lineStarts[i]<posn;++i)
- ;
-
- /* Allow for character at start of line */
- if(i < (*teh)->nLines && (*teh)->lineStarts[i]==posn)
- ++i;
-
- if(tobottom)
- {
- short max = GetCtlMax(VSCROLL(windex));
- if( i > max)
- i = max+1;
- }
-
- SetCtlValue(VSCROLL(windex),i-1);
- AdjustText(windex);
- }
- }
-
-
- /*
- Scroll the window so the current selection is on screen, if this
- isn't currently the case.
- */
-
- ScrollToSelection(windex)
- int windex;
- {
- if(isLegalWindow(windex))
- {
- TEHandle teh = TEHANDLE(windex);
- Rect vr;
- short top, bottom, height, max;
-
- vr = (*teh)->viewRect;
-
- top = GetCtlValue(VSCROLL(windex))-1;
- height = (vr.bottom-vr.top)/(*teh)->lineHeight;
- bottom = top + height;
-
- max = GetCtlMax(VSCROLL(windex));
-
- if(max == 1)
- AdjustText(windex);
-
- else if ((*teh)->selEnd < (*teh)->lineStarts[top])
- ScrollCharacter(windex,(*teh)->selStart,FALSE);
-
- else if ((*teh)->selStart >= (*teh)->lineStarts[bottom])
- ScrollCharacter(windex,(*teh)->selEnd,TRUE);
- }
- }
-